// Copyright 2024 The longwisetool Authors. All rights reserved.

// Project: longwisetool
// CodeName: 朗知小工具
// IDE: GoLand
// Author: fucaihe@outlook.com
// File: main.go
// Date: 2024/02/28 11:23:54
// Description: 朗知小工具

package main

import (
	"fmt"
	"os"
	"sort"
	"strings"
	"time"

	"github.com/shopspring/decimal"
	"github.com/xuri/excelize/v2"
)

// 排名导出
var exportRankMap map[string][]ExportRank

var mediaListMap map[string]struct{}
var kolListMap map[string]struct{}

// 加载媒体KOL数据
func loadingMediaKOLData() {
	fmt.Println("loading media_kol_data.xlsx")
	f, err := excelize.OpenFile("media_kol_data.xlsx")
	if err != nil {
		panic(err)
	}
	defer func() { _ = f.Close() }()

	mediaListMap = make(map[string]struct{})

	// 媒体
	mediaSheetName := f.GetSheetName(0)

	// 加载表头字段名
	mediaColMap := make(map[string]int)
	for i := 1; i < excelize.MaxColumns; i++ {
		cell, _ := excelize.CoordinatesToCellName(i, 1)
		cellValue, _ := f.GetCellValue(mediaSheetName, cell)
		cellValue = strings.TrimSpace(cellValue)
		if cellValue == "" {
			break
		}
		mediaColMap[cellValue] = i
	}

	fmt.Println("get media_kol_data.xlsx " + mediaSheetName + " sheet data")

	// 获取媒体数据
	mediaRows, err := f.GetRows(mediaSheetName)
	if err != nil {
		panic(err)
	}
	// 遍历所有数据
	for i, row := range mediaRows {
		if i == 0 {
			continue
		}
		mediaName := strings.TrimSpace(row[mediaColMap["媒体"]-1])
		mediaListMap[mediaName] = struct{}{}
	}

	// KOL
	kolListMap = make(map[string]struct{})
	kolSheetName := f.GetSheetName(1)

	// 加载表头字段名
	kolColMap := make(map[string]int)
	for i := 1; i < excelize.MaxColumns; i++ {
		cell, _ := excelize.CoordinatesToCellName(i, 1)
		cellValue, _ := f.GetCellValue(kolSheetName, cell)
		cellValue = strings.TrimSpace(cellValue)
		if cellValue == "" {
			break
		}
		kolColMap[cellValue] = i
	}

	fmt.Println("get media_kol_data.xlsx " + kolSheetName + " sheet data")

	// 获取KOL数据
	kolRows, err := f.GetRows(kolSheetName)
	if err != nil {
		panic(err)
	}
	// 遍历所有数据
	for i, row := range kolRows {
		if i == 0 {
			continue
		}
		kolName := strings.TrimSpace(row[kolColMap["自媒体"]-1])
		kolListMap[kolName] = struct{}{}
	}
}

func main() {
	// 加载媒体KOL数据
	loadingMediaKOLData()

	// 读取源数据
	fmt.Println("loading source_data.xlsx")
	f, err := excelize.OpenFile("source_data.xlsx")
	if err != nil {
		panic(err)
	}
	defer func() { _ = f.Close() }()

	sheetName := f.GetSheetName(0)

	// 加载表头字段名
	colMap := make(map[string]int)
	for i := 1; i < excelize.MaxColumns; i++ {
		cell, _ := excelize.CoordinatesToCellName(i, 1)
		cellValue, _ := f.GetCellValue(sheetName, cell)
		cellValue = strings.TrimSpace(cellValue)
		if cellValue == "" {
			break
		}
		colMap[cellValue] = i
	}

	fmt.Println("get " + sheetName + " sheet data")
	// 获取数据
	rows, err := f.GetRows(sheetName)
	if err != nil {
		panic(err)
	}

	// 频道数量统计
	channelCountMap := make(map[string]int)

	// 媒体榜单 - 各频道发文量统计
	shishangMediaNewsChannel := make(map[string]int)
	dongchediMediaNewsChannel := make(map[string]int)
	shumaMediaNewsChannel := make(map[string]int)
	kejiMediaNewsChannel := make(map[string]int)
	tuijianMediaNewsChannel := make(map[string]int)

	// KOL榜单 - 各频道发文量统计
	shishangKOLNewsChannel := make(map[string]int)
	dongchediKOLNewsChannel := make(map[string]int)
	shumaKOLNewsChannel := make(map[string]int)
	kejiKOLNewsChannel := make(map[string]int)
	tuijianKOLNewsChannel := make(map[string]int)

	// 遍历所有数据
	for i, row := range rows {
		if i == 0 {
			continue
		}

		channelName := strings.TrimSpace(row[colMap["节点名称"]-1])
		// title := strings.TrimSpace(row[colMap["标题"]-1])
		author := strings.TrimSpace(row[colMap["作者"]-1])
		// link := strings.TrimSpace(row[colMap["原文链接"]-1])
		// wordCount := strings.TrimSpace(row[colMap["字数"]-1])
		// readCount := strings.TrimSpace(row[colMap["阅读量"]-1])
		// commentCount := strings.TrimSpace(row[colMap["评论量"]-1])
		// likeCount := strings.TrimSpace(row[colMap["点赞量"]-1])
		// forwardCount := strings.TrimSpace(row[colMap["转发量"]-1])
		// releaseTimeTxt := strings.TrimSpace(row[colMap["发布时间"]-1])

		// 频道数量统计
		channelCount, ok := channelCountMap[channelName]
		if ok {
			channelCountMap[channelName] = channelCount + 1
		} else {
			channelCountMap[channelName] = 1
		}

		// 是否匹配到媒体列表
		_, mOk := mediaListMap[author]
		if mOk {
			// 媒体发文量统计
			switch channelName {
			case "时尚列表":
				shishangMediaNewsCount, ok := shishangMediaNewsChannel[author]
				if ok {
					shishangMediaNewsChannel[author] = shishangMediaNewsCount + 1
				} else {
					shishangMediaNewsChannel[author] = 1
				}
			case "懂车帝列表":
				dongchediMediaNewsCount, ok := dongchediMediaNewsChannel[author]
				if ok {
					dongchediMediaNewsChannel[author] = dongchediMediaNewsCount + 1
				} else {
					dongchediMediaNewsChannel[author] = 1
				}
			case "数码列表":
				shumaMediaNewsCount, ok := shumaMediaNewsChannel[author]
				if ok {
					shumaMediaNewsChannel[author] = shumaMediaNewsCount + 1
				} else {
					shumaMediaNewsChannel[author] = 1
				}
			case "科技列表":
				kejiMediaNewsCount, ok := kejiMediaNewsChannel[author]
				if ok {
					kejiMediaNewsChannel[author] = kejiMediaNewsCount + 1
				} else {
					kejiMediaNewsChannel[author] = 1
				}
			case "推荐列表":
				tuijianMediaNewsCount, ok := tuijianMediaNewsChannel[author]
				if ok {
					tuijianMediaNewsChannel[author] = tuijianMediaNewsCount + 1
				} else {
					tuijianMediaNewsChannel[author] = 1
				}
			}
		} else {
			// 除了媒体就是KOL
			// 媒体发文量统计
			switch channelName {
			case "时尚列表":
				shishangKOLNewsCount, ok := shishangKOLNewsChannel[author]
				if ok {
					shishangKOLNewsChannel[author] = shishangKOLNewsCount + 1
				} else {
					shishangKOLNewsChannel[author] = 1
				}
			case "懂车帝列表":
				dongchediKOLNewsCount, ok := dongchediKOLNewsChannel[author]
				if ok {
					dongchediKOLNewsChannel[author] = dongchediKOLNewsCount + 1
				} else {
					dongchediKOLNewsChannel[author] = 1
				}
			case "数码列表":
				shumaKOLNewsCount, ok := shumaKOLNewsChannel[author]
				if ok {
					shumaKOLNewsChannel[author] = shumaKOLNewsCount + 1
				} else {
					shumaKOLNewsChannel[author] = 1
				}
			case "科技列表":
				kejiKOLNewsCount, ok := kejiKOLNewsChannel[author]
				if ok {
					kejiKOLNewsChannel[author] = kejiKOLNewsCount + 1
				} else {
					kejiKOLNewsChannel[author] = 1
				}
			case "推荐列表":
				tuijianKOLNewsCount, ok := tuijianKOLNewsChannel[author]
				if ok {
					tuijianKOLNewsChannel[author] = tuijianKOLNewsCount + 1
				} else {
					tuijianKOLNewsChannel[author] = 1
				}
			}
		}

		// 是否匹配到KOL列表
		// _, kOk := kolListMap[author]
		// if kOk {
		// 	// 媒体发文量统计
		// 	switch channelName {
		// 	case "时尚列表":
		// 		shishangKOLNewsCount, ok := shishangKOLNewsChannel[author]
		// 		if ok {
		// 			shishangKOLNewsChannel[author] = shishangKOLNewsCount + 1
		// 		} else {
		// 			shishangKOLNewsChannel[author] = 1
		// 		}
		// 	case "懂车帝列表":
		// 		dongchediKOLNewsCount, ok := dongchediKOLNewsChannel[author]
		// 		if ok {
		// 			dongchediKOLNewsChannel[author] = dongchediKOLNewsCount + 1
		// 		} else {
		// 			dongchediKOLNewsChannel[author] = 1
		// 		}
		// 	case "数码列表":
		// 		shumaKOLNewsCount, ok := shumaKOLNewsChannel[author]
		// 		if ok {
		// 			shumaKOLNewsChannel[author] = shumaKOLNewsCount + 1
		// 		} else {
		// 			shumaKOLNewsChannel[author] = 1
		// 		}
		// 	case "科技列表":
		// 		kejiKOLNewsCount, ok := kejiKOLNewsChannel[author]
		// 		if ok {
		// 			kejiKOLNewsChannel[author] = kejiKOLNewsCount + 1
		// 		} else {
		// 			kejiKOLNewsChannel[author] = 1
		// 		}
		// 	case "推荐列表":
		// 		tuijianKOLNewsCount, ok := tuijianKOLNewsChannel[author]
		// 		if ok {
		// 			tuijianKOLNewsChannel[author] = tuijianKOLNewsCount + 1
		// 		} else {
		// 			tuijianKOLNewsChannel[author] = 1
		// 		}
		// 	}
		// }
	}

	// 打印各频道的总数据量
	// for channel, count := range channelCountMap {
	//	fmt.Println(channel, count)
	// }

	// 媒体榜单-推荐频道
	// var mTJSlice RankSlice
	// for channel, count := range tuijianMediaNewsChannel {
	//	mTJSlice = append(mTJSlice, Rank{
	//		Name:  channel,
	//		Count: count,
	//	})
	// }
	//
	// sort.Sort(mTJSlice)
	//
	// mTJSlice = mTJSlice[:100]
	// for i, data := range mTJSlice {
	//	// 单频道媒体推荐量算法 -> 单一媒体露出总信息量/单一频道月度总信息量*10000=推荐量
	//	tmpA := float64(data.Count) / float64(channelCountMap["推荐列表"])
	//	tuijianRankCount, _ := decimal.NewFromFloat(tmpA * 10000).Round(1).Float64()
	//	fmt.Println(i, data.Name, data.Count, tuijianRankCount)
	// }

	exportRankMap = make(map[string][]ExportRank)

	topN := 100
	// 媒体榜单 - 推荐频道
	fmt.Println("---------- 媒体榜单 ↓ 推荐列表 ----------")
	echoMediaRank("媒体榜单-推荐", tuijianMediaNewsChannel, channelCountMap["推荐列表"], topN)
	fmt.Println("---------- 媒体榜单 ↑ 推荐列表 ----------")

	// 媒体榜单 - 科技频道
	fmt.Println("---------- 媒体榜单 ↓ 科技列表 ----------")
	echoMediaRank("媒体榜单-科技", kejiMediaNewsChannel, channelCountMap["科技列表"], topN)
	fmt.Println("---------- 媒体榜单 ↑ 科技列表 ----------")

	// 媒体榜单 - 时尚列表
	fmt.Println("---------- 媒体榜单 ↓ 时尚列表 ----------")
	echoMediaRank("媒体榜单-时尚", shishangMediaNewsChannel, channelCountMap["时尚列表"], topN)
	fmt.Println("---------- 媒体榜单 ↑ 时尚列表 ----------")

	// 媒体榜单 - 数码列表
	fmt.Println("---------- 媒体榜单 ↓ 数码列表 ----------")
	echoMediaRank("媒体榜单-数码", shumaMediaNewsChannel, channelCountMap["数码列表"], topN)
	fmt.Println("---------- 媒体榜单 ↑ 数码列表 ----------")

	// 媒体榜单 - 懂车帝列表
	fmt.Println("---------- 媒体榜单 ↓ 懂车帝列表 ----------")
	echoMediaRank("媒体榜单-懂车帝", dongchediMediaNewsChannel, channelCountMap["懂车帝列表"], topN)
	fmt.Println("---------- 媒体榜单 ↑ 懂车帝列表 ----------")

	// KOL榜单 - 推荐频道
	fmt.Println("---------- KOL榜单 ↓ 推荐列表 ----------")
	echoMediaRank("KOL榜单-推荐", tuijianKOLNewsChannel, channelCountMap["推荐列表"], topN)
	fmt.Println("---------- KOL榜单 ↑ 推荐列表 ----------")

	// KOL榜单 - 科技频道
	fmt.Println("---------- KOL榜单 ↓ 科技列表 ----------")
	echoMediaRank("KOL榜单-科技", kejiKOLNewsChannel, channelCountMap["科技列表"], topN)
	fmt.Println("---------- KOL榜单 ↑ 科技列表 ----------")

	// KOL榜单 - 时尚列表
	fmt.Println("---------- KOL榜单 ↓ 时尚列表 ----------")
	echoMediaRank("KOL榜单-时尚", shishangKOLNewsChannel, channelCountMap["时尚列表"], topN)
	fmt.Println("---------- KOL榜单 ↑ 时尚列表 ----------")

	// KOL榜单 - 数码列表
	fmt.Println("---------- KOL榜单 ↓ 数码列表 ----------")
	echoMediaRank("KOL榜单-数码", shumaKOLNewsChannel, channelCountMap["数码列表"], topN)
	fmt.Println("---------- KOL榜单 ↑ 数码列表 ----------")

	// KOL榜单 - 懂车帝列表
	fmt.Println("---------- KOL榜单 ↓ 懂车帝列表 ----------")
	echoMediaRank("KOL榜单-懂车帝", dongchediKOLNewsChannel, channelCountMap["懂车帝列表"], topN)
	fmt.Println("---------- KOL榜单 ↑ 懂车帝列表 ----------")

	// 导出榜单到Excel
	// 写入表头
	//for i, headName := range []string{"排名", "媒体号","推荐量"} {
	//	axis, _ := excelize.CoordinatesToCellName(i+1, 1)
	//	_ = f.SetCellValue("", axis, headName)
	//}

	// 排序
	sKeys := make([]string, 0, len(exportRankMap))
	for key := range exportRankMap {
		sKeys = append(sKeys, key)
	}
	sort.Strings(sKeys)

	// 创建一个Excel
	exportF := excelize.NewFile()
	for _, key := range sKeys {
		values := exportRankMap[key]
		_, _ = exportF.NewSheet(key)
		bHead := ""
		if strings.Contains(key, "媒体榜单") {
			bHead = "媒体号"
		} else if strings.Contains(key, "KOL榜单") {
			bHead = "KOL号"
		}
		_ = exportF.SetCellValue(key, "A1", "排名")
		_ = exportF.SetCellValue(key, "B1", bHead)
		_ = exportF.SetCellValue(key, "C1", "推荐量")

		for i, data := range values {
			_ = exportF.SetCellValue(key, fmt.Sprintf("A%d", i+2), data.Index)                           // 排名
			_ = exportF.SetCellValue(key, fmt.Sprintf("B%d", i+2), data.Name)                            // 媒体号/KOL号
			_ = exportF.SetCellStr(key, fmt.Sprintf("C%d", i+2), fmt.Sprintf("%.1f", data.TuijianCount)) // 推荐量
		}
	}
	// 删除第一页Sheet
	_ = exportF.DeleteSheet(exportF.GetSheetName(0))

	// 保存文件
	exportFilePath := "榜单数据-" + time.Now().Format("20060102150405") + ".xlsx"

	// 删除旧文件
	_ = os.Remove(exportFilePath)

	if err = exportF.SaveAs(exportFilePath); err != nil {
		panic(err)
	}
	fmt.Println("export excel ok", exportFilePath)
}

// 媒体榜单 - 科技频道
// dataMap - 媒体作者发文数据
// channelNewsCount - 频道发文数量
func echoMediaRank(sheet string, dataMap map[string]int, channelNewsCount int, topN int) {
	// 媒体榜单-推荐频道
	var rankSlice RankSlice
	for channel, count := range dataMap {
		rankSlice = append(rankSlice, Rank{
			Name:  channel,
			Count: count,
		})
	}

	sort.Sort(rankSlice)

	if len(rankSlice) > topN {
		rankSlice = rankSlice[:topN]
	}

	for i, data := range rankSlice {
		// 单频道媒体推荐量算法 -> 单一媒体露出总信息量/单一频道月度总信息量*10000=推荐量
		tmpA := float64(data.Count) / float64(channelNewsCount)
		rankCount, _ := decimal.NewFromFloat(tmpA * 10000).Round(1).Float64()

		fmt.Printf("%d %s %d %.1f\n", i+1, data.Name, data.Count, rankCount)

		tmpSlice, tpOk := exportRankMap[sheet]
		if tpOk {
			tmpSlice = append(tmpSlice, ExportRank{
				Index:        i + 1,
				Name:         data.Name,
				TuijianCount: rankCount,
			})
			exportRankMap[sheet] = tmpSlice
		} else {
			exportRankMap[sheet] = []ExportRank{{
				Index:        i + 1,
				Name:         data.Name,
				TuijianCount: rankCount,
			}}
		}
	}
}

// Rank 榜单
type Rank struct {
	Name  string
	Count int
}

type RankSlice []Rank

func (r RankSlice) Len() int {
	return len(r)
}

func (r RankSlice) Swap(i, j int) {
	r[i], r[j] = r[j], r[i]
}

// Less 重写方法, 从count高到底排序
func (r RankSlice) Less(i, j int) bool {
	return r[i].Count > r[j].Count
}

// ExportRank 导出数据
type ExportRank struct {
	Index        int     // 排名
	Name         string  // 媒体名称/KOL名称
	TuijianCount float64 // 推荐量
}
